Fix #477175, reported by Juri Pakaste.
authorKristian Rietveld <kris@imendio.com>
Thu, 10 Jan 2008 09:24:11 +0000 (09:24 +0000)
committerKristian Rietveld <kristian@src.gnome.org>
Thu, 10 Jan 2008 09:24:11 +0000 (09:24 +0000)
2008-01-10  Kristian Rietveld  <kris@imendio.com>

Fix #477175, reported by Juri Pakaste.

* gtk/gtktreeprivate.h:
* gtk/gtktreeview.c (gtk_tree_view_top_row_to_dy): do not set
tree_view->priv->dy here directly, just calculate the new value
and set it on the adjustment,
(gtk_tree_view_adjustment_changed): add guards to not call
gtk_tree_view_dy_to_top_row() if we are currently in
gtk_tree_view_top_row_to_dy(),
(gtk_tree_view_put): fix coordinate annotation: these are bin_window
coordinates, not tree coordinates,
(gtk_tree_view_real_start_editing): add cast.

* gtk/tests/treeview-scrolling.c: add an assertion for checking the
position of the editable in the "create new row and start editing"
tests.

svn path=/trunk/; revision=19331

ChangeLog
gtk/gtktreeprivate.h
gtk/gtktreeview.c
gtk/tests/treeview-scrolling.c

index 5ae3f3cd781768b212412c9e40414de4bcb1fe03..607fb3b0bdc894bb352a095c8550b3b2eb4d95d9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2008-01-10  Kristian Rietveld  <kris@imendio.com>
+
+       Fix #477175, reported by Juri Pakaste.
+
+       * gtk/gtktreeprivate.h:
+       * gtk/gtktreeview.c (gtk_tree_view_top_row_to_dy): do not set
+       tree_view->priv->dy here directly, just calculate the new value
+       and set it on the adjustment,
+       (gtk_tree_view_adjustment_changed): add guards to not call
+       gtk_tree_view_dy_to_top_row() if we are currently in
+       gtk_tree_view_top_row_to_dy(),
+       (gtk_tree_view_put): fix coordinate annotation: these are bin_window
+       coordinates, not tree coordinates,
+       (gtk_tree_view_real_start_editing): add cast.
+
+       * gtk/tests/treeview-scrolling.c: add an assertion for checking the
+       position of the editable in the "create new row and start editing"
+       tests.
+
 2008-01-09  Michael Natterer  <mitch@imendio.com>
 
        * gtk/gtkcolorsel.c (make_label_spinbutton): remove unused
index 9d49f394df0cff8a8ae55ed6ee2fd23222e10025..3d643f9e383b250da141be19739d2fda156b0696 100644 (file)
@@ -221,6 +221,8 @@ struct _GtkTreeViewPrivate
 
   guint init_hadjust_value : 1;
 
+  guint in_top_row_to_dy : 1;
+
   /* interactive search */
   guint enable_search : 1;
   guint disable_popdown : 1;
index 720cd0f9dc2d5ae07700c36392a87f68965bb8a4..5ecb438610c40b7be6451dc78b220f340ddae9bd 100644 (file)
@@ -6368,6 +6368,7 @@ gtk_tree_view_top_row_to_dy (GtkTreeView *tree_view)
   GtkTreePath *path;
   GtkRBTree *tree;
   GtkRBNode *node;
+  int new_dy;
 
   if (tree_view->priv->top_row)
     path = gtk_tree_row_reference_get_path (tree_view->priv->top_row);
@@ -6401,16 +6402,17 @@ gtk_tree_view_top_row_to_dy (GtkTreeView *tree_view)
       return;
     }
 
-  tree_view->priv->dy = _gtk_rbtree_node_find_offset (tree, node);
-  tree_view->priv->dy += tree_view->priv->top_row_dy;
+  new_dy = _gtk_rbtree_node_find_offset (tree, node);
+  new_dy += tree_view->priv->top_row_dy;
 
-  if (tree_view->priv->dy + tree_view->priv->vadjustment->page_size > tree_view->priv->height)
-    tree_view->priv->dy = tree_view->priv->height - tree_view->priv->vadjustment->page_size;
+  if (new_dy + tree_view->priv->vadjustment->page_size > tree_view->priv->height)
+    new_dy = tree_view->priv->height - tree_view->priv->vadjustment->page_size;
 
-  tree_view->priv->dy = MAX (0, tree_view->priv->dy);
+  new_dy = MAX (0, new_dy);
 
-  gtk_adjustment_set_value (tree_view->priv->vadjustment,
-                           (gdouble)tree_view->priv->dy);
+  tree_view->priv->in_top_row_to_dy = TRUE;
+  gtk_adjustment_set_value (tree_view->priv->vadjustment, (gdouble)new_dy);
+  tree_view->priv->in_top_row_to_dy = FALSE;
 }
 
 
@@ -8082,7 +8084,7 @@ gtk_tree_view_real_move_cursor (GtkTreeView       *tree_view,
 static void
 gtk_tree_view_put (GtkTreeView *tree_view,
                   GtkWidget   *child_widget,
-                  /* in tree coordinates */
+                  /* in bin_window coordinates */
                   gint         x,
                   gint         y,
                   gint         width,
@@ -10614,7 +10616,9 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment,
         {
           /* update our dy and top_row */
           tree_view->priv->dy = (int) tree_view->priv->vadjustment->value;
-          gtk_tree_view_dy_to_top_row (tree_view);
+
+          if (!tree_view->priv->in_top_row_to_dy)
+            gtk_tree_view_dy_to_top_row (tree_view);
        }
     }
 }
@@ -14793,8 +14797,7 @@ gtk_tree_view_real_start_editing (GtkTreeView       *tree_view,
   _gtk_tree_view_column_start_editing (column, GTK_CELL_EDITABLE (cell_editable));
 
   gtk_tree_view_real_set_cursor (tree_view, path, FALSE, TRUE);
-
-  cell_area->y += pre_val - tree_view->priv->vadjustment->value;
+  cell_area->y += pre_val - (int)tree_view->priv->vadjustment->value;
 
   gtk_widget_size_request (GTK_WIDGET (cell_editable), &requisition);
 
index 90e6ab234152194206ef215e1977cc95151736a3..5ee24c123bb2e6650a8ba4043e64ed3861eb9fd4 100644 (file)
@@ -668,6 +668,34 @@ create_new_row (GtkListStore *store,
        gtk_list_store_set (store, iter, 0, "New...", -1);
 }
 
+static void
+scroll_new_row_editing_started (GtkCellRenderer *cell,
+                               GtkCellEditable *editable,
+                               const char      *path,
+                               gpointer         user_data)
+{
+       GtkWidget **widget = user_data;
+
+       *widget = GTK_WIDGET (editable);
+}
+
+static void
+test_editable_position (GtkWidget   *tree_view,
+                       GtkWidget   *editable,
+                       GtkTreePath *cursor_path)
+{
+       GdkRectangle rect;
+       GtkAdjustment *vadj;
+
+       gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
+                                          cursor_path, NULL, &rect);
+
+       vadj = gtk_tree_view_get_vadjustment (GTK_TREE_VIEW (tree_view));
+
+       /* There are all in bin_window coordinates */
+       g_assert (editable->allocation.y == rect.y + ((rect.height - editable->allocation.height) / 2));
+}
+
 static void
 scroll_new_row (ScrollFixture *fixture,
                gconstpointer  test_data)
@@ -675,6 +703,9 @@ scroll_new_row (ScrollFixture *fixture,
        GtkTreeIter scroll_iter;
        GtkTreePath *scroll_path;
        GtkTreeModel *model;
+       GList *renderers;
+       GtkTreeViewColumn *column;
+       GtkWidget *editable;
 
        /* The aim of this test is creating a new row at several places,
         * and immediately put the cursor on it.  TreeView should correctly
@@ -695,10 +726,19 @@ scroll_new_row (ScrollFixture *fixture,
        create_new_row (GTK_LIST_STORE (model), GPOINTER_TO_INT (test_data),
                        &scroll_iter);
 
+       /* Set up a signal handler to acquire the editable widget */
+       column = gtk_tree_view_get_column (GTK_TREE_VIEW (fixture->tree_view), 0);
+       renderers = gtk_tree_view_column_get_cell_renderers (column);
+
+       g_signal_connect (G_OBJECT (renderers->data), "editing-started",
+                         G_CALLBACK (scroll_new_row_editing_started),
+                         &editable);
+
+       /* Now set the cursor on the path and start editing */
        scroll_path = gtk_tree_model_get_path (model, &scroll_iter);
        gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view),
                                  scroll_path,
-                                 gtk_tree_view_get_column (GTK_TREE_VIEW (fixture->tree_view), 0),
+                                 column,
                                  TRUE);
 
        while (gtk_events_pending ())
@@ -707,6 +747,7 @@ scroll_new_row (ScrollFixture *fixture,
        /* Test position */
        test_position (GTK_TREE_VIEW (fixture->tree_view), scroll_path,
                       FALSE, 0.0, 0.0);
+       test_editable_position (fixture->tree_view, editable, scroll_path);
 
        gtk_tree_path_free (scroll_path);
 }